from flask import Flask, jsonify
# from flask import render_template
from flask import request
from flask_cors import CORS


# import graph
# from KG import askInGraph
# from NLU import comprehendQue
# from utils import constructAns

import json
import requests
import subprocess
import threading
import time

app = Flask(__name__)
CORS(app, resources=r"/*")


def run_model(): # 启动模型，两用
    # 这里可以定义启动服务的控制台命令
    command = "rasa run -m models --enable-api"
    try:
        # 执行控制台命令，并等待命令执行完成
        subprocess.run(command, shell=True, check=True)
        return True
    except subprocess.CalledProcessError as e:
        print(f"启动服务失败：{e}")
        return False

def start_actions(): # 启动动作服务器，两用
    # 这里可以定义启动服务的控制台命令
    command = "rasa run actions"
    try:
        # 执行控制台命令，并等待命令执行完成
        subprocess.run(command, shell=True, check=True)
        return True
    except subprocess.CalledProcessError as e:
        print(f"启动服务失败：{e}")
        return False
def inject_nlu(): # 创建nlu，两用
    print("injecting nlu")
    command_to_inject = "python create_nlu.py"
    try:
        # result = subprocess.run(command_to_run, capture_output=True, text=True, shell=True)
        result = subprocess.run(command_to_inject, capture_output=True, text=True, shell=True)

        # 检查命令是否成功执行（退出状态码为0）
        if result.returncode == 0:
            print("nlu injected successfully")
        else:
            # 输出标准错误信息
            print("Error output:")
            print(result.stderr)
    except  subprocess.CalledProcessError as e:
        print(f"error:{e}")

def train_rasa(): # 训练模型，两用
    print("training rasa model")
    command_to_inject = "rasa train"
    try:
        # result = subprocess.run(command_to_run, capture_output=True, text=True, shell=True)
        result = subprocess.run(command_to_inject, capture_output=True, text=True, shell=True)

        # 检查命令是否成功执行（退出状态码为0）
        if result.returncode == 0:
            print("rasa model trained successfully")
        else:
            # 输出标准错误信息
            print("Error output:")
            print(result.stderr)
    except  subprocess.CalledProcessError as e:
        print(f"error:{e}")
def start_service(): # 启动服务，两用
    # 创建一个线程来启动rasa actions
    thread_actions = threading.Thread(target=start_actions)
    thread_actions.start()
    # 创建一个线程来运行rasa模型
    thread_model = threading.Thread(target=run_model)
    thread_model.start()
    # thread_model.join() # 通常模型加载时间更长，等待模型加载完毕才返回相应信息
    # 等待一段时间（约为2分）
    time.sleep(120)
    # 返回启动服务的响应
    response = {'message': 'Server Prepared'}
    return jsonify(response), 200

def run_easyinstruct(activate_cmd, command_to_run_rte, command_to_run_att):
    full_command = f"{activate_cmd} && {command_to_run_rte} && {command_to_run_att}"
    # subprocess.run(activate_cmd, shell=True, check=True)

    # 在激活的 Conda 环境中执行指定的命令
    try:
        # result = subprocess.run(command_to_run, capture_output=True, text=True, shell=True)
        result = subprocess.run(full_command, capture_output=True, text=True, shell=True)

        # 检查命令是否成功执行（退出状态码为0）
        if result.returncode == 0:
            print("csv created successfully")
        else:
            # 输出标准错误信息
            print("Error output:")
            print(result.stderr)
    except  subprocess.CalledProcessError as e:
        print(f"error:{e}")

def create_csv():
    print("creating_csv")
    # 指定 Conda 环境的激活脚本路径
    activate_script = r"D:\Miniconda\Scripts\activate.bat"
    conda_environment = "easyinstruct"  # 要激活的 Conda 环境名
    command_to_run_rte = "python rtecreate.py"
    command_to_run_att = "python attcreate.py"

    # 构建完整的激活命令
    activate_cmd = f"\"{activate_script}\" {conda_environment}"

    try:
        # 使用 subprocess 执行激活命令
        thread_easyinstruct = threading.Thread(target=run_easyinstruct, args=(activate_cmd, command_to_run_rte, command_to_run_att))
        thread_easyinstruct.start()
        # print("started")
        thread_easyinstruct.join()
        return {
            "success": True,
            "error": None
        }
    except subprocess.CalledProcessError as e:
        # 捕获命令执行过程中的异常
        return {
            "success": False,
            "error": str(e)
        }
def transfer_csv():
    print("transferring csv")
    command_to_inject = "python transfer.py"
    try:
        # result = subprocess.run(command_to_run, capture_output=True, text=True, shell=True)
        result = subprocess.run(command_to_inject, capture_output=True, text=True, shell=True)

        # 检查命令是否成功执行（退出状态码为0）
        if result.returncode == 0:
            print("graph created successfully")
        else:
            # 输出标准错误信息
            print("Error output:")
            print(result.stderr)
    except  subprocess.CalledProcessError as e:
        print(f"error:{e}")

def inject_graph():
    print("injecting individual graph")
    command_to_inject = "python csv2neo4j.py"
    try:
        # result = subprocess.run(command_to_run, capture_output=True, text=True, shell=True)
        result = subprocess.run(command_to_inject, capture_output=True, text=True, shell=True)

        # 检查命令是否成功执行（退出状态码为0）
        if result.returncode == 0:
            print("graph created successfully")
        else:
            # 输出标准错误信息
            print("Error output:")
            print(result.stderr)
    except  subprocess.CalledProcessError as e:
        print(f"error:{e}")


def get_file():
    print("getting_File")
    file_name = 'posted.txt'
    altogether = ""
    with open(file_name, "r", encoding='utf-8') as input_file:
        lines = input_file.readlines()
        for line in lines:
            altogether += line.rstrip()

    with open("run.yaml", "r", encoding='utf-8') as file_before:
        lines_before = file_before.readlines()
    lines_before[5] = f"text_input: {altogether}\n"
    with open("run.yaml", "w", encoding='utf-8') as file_after:
        for line in lines_before:
            file_after.write(line)

@app.route('/start_individual', methods=['GET', 'Post'])
def start_individual():
    # 接收前端传过来的纯文件
    thread_file = threading.Thread(target=get_file)
    thread_file.start()
    thread_file.join()
    # 创建一个线程来将文本转化为csv
    thread_csv = threading.Thread(target=create_csv)
    thread_csv.start()
    thread_csv.join()
    # 创建一个线程将csv转化为英文
    thread_transfer = threading.Thread(target=transfer_csv)
    thread_transfer.start()
    thread_transfer.join()
    # 创建一个线程来将csv内容注入到neo4j里面，并读取各个类型的实体
    thread_inject = threading.Thread(target=inject_graph)
    thread_inject.start()
    thread_inject.join()
    # region nlu-and-train
    # 基于entities，生成vocabulary和nlu
    thread_nlu = threading.Thread(target=inject_nlu)
    thread_nlu.start()
    thread_nlu.join()
    # 训练rasa模型
    thread_rasa = threading.Thread(target=train_rasa)
    thread_rasa.start()
    thread_rasa.join()
    # endregion
    # 开启服务
    thread_service = threading.Thread(target=start_service)
    thread_service.start()
    thread_service.join()
    # 返回启动服务的响应
    response = {'message': 'Individual Graph Created'}
    return jsonify(response), 200

def inject_general():
    print("injecting general graph")
    command_to_inject = "python build_medicalgraph_part.py"
    try:
        # result = subprocess.run(command_to_run, capture_output=True, text=True, shell=True)
        result = subprocess.run(command_to_inject, capture_output=True, text=True, shell=True)

        # 检查命令是否成功执行（退出状态码为0）
        if result.returncode == 0:
            print("general graph created successfully")
        else:
            # 输出标准错误信息
            print("Error output:")
            print(result.stderr)
    except  subprocess.CalledProcessError as e:
        print(f"error:{e}")

@app.route('/start_general', methods=['GET', 'Post'])
def start_general():
    # 建通用图
    thread_general = threading.Thread(target=inject_general)
    thread_general.start()
    thread_general.join()
    # region nlu-and-train
    # 生成vocabulary和nlu
    thread_nlu = threading.Thread(target=inject_nlu)
    thread_nlu.start()
    thread_nlu.join()
    # 训练rasa模型
    thread_rasa = threading.Thread(target=train_rasa)
    thread_rasa.start()
    thread_rasa.join()
    # endregion
    # 开启服务
    thread_service = threading.Thread(target=start_service)
    thread_service.start()
    thread_service.join()
    response = {'message': 'General Service Prepared'}
    return jsonify(response), 200

# # for rasa
@app.route('/SendMessage', methods=['POST', 'GET'] )
def extract(): # 把消息发送给rasa，获得rasa的回复
  data = request.get_json()
  print(data)
  # sender = data['Sender']
  message = data['sentence']
  print(message)
  payload = json.dumps({"sender": "Rasa","message": message})
  headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
  response = requests.request("POST",  url="http://localhost:5005/webhooks/rest/webhook", headers=headers, data=payload)
  response = response.json()
  result = response[0]['text']
  newResponse = {
      # 'Sender': sender,
      'Message': result
  }
  return jsonify(newResponse)



if __name__ == '__main__':
    # graph.main()  # 建图
    app.run(debug=True, port=5050)
